/*
 * Copyright (c) 2010 CCX(China) Co.,Ltd. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * CCX(China) Co.,Ltd. ("Confidential Information").
 * It may not be copied or reproduced in any manner without the express 
 * written permission of CCX(China) Co.,Ltd.
 * 
 *	Created on 2010-12-13 下午05:16:14
 */
package cn.com.ccxe.core.db;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.ccxe.core.db.util.ArticleLinkCompartor;
import cn.com.ccxe.core.db.util.ArticleLinkTupleBinding;
import cn.com.ccxe.core.entity.ArticleLink;

import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;

public class WebWorkQueues extends BasicDB<ArticleLink> {

	private static final Logger logger = LoggerFactory.getLogger(WebWorkQueues.class);
	private static final String DATABASE_NAME = "WORK_QUEUES";
	private static Environment environment;
	private static final String DATABASE_PATH = "E:/myworkspace/monitor/db/WORK_QUEUES";
	private static WebWorkQueues WEB_WORK_QUEUES;
	
	WebWorkQueues() throws Exception {
		environment = setup(DATABASE_PATH);
		DatabaseConfig dbConfig = new DatabaseConfig();
		dbConfig.setAllowCreate(true);
		dbConfig.setTransactional(false);
		dbConfig.setDeferredWrite(true);
		dbConfig.setDuplicateComparator(getComparator());// 设置判断重复的比较器
		dbConfig.setSortedDuplicates(false);// 是否允许重复的记录
		database = environment.openDatabase(null, DATABASE_PATH, dbConfig);
		if(database != null) {
			logger.info("数据库【{}】创建成功",DATABASE_NAME);
		}
	}
	
	public synchronized static WebWorkQueues getInstance() {
		try {
			if (WEB_WORK_QUEUES == null) {
				logger.info("数据库【{}】未被创建，将重新创建！", DATABASE_NAME);
				WEB_WORK_QUEUES = new WebWorkQueues();
				return WEB_WORK_QUEUES;
			}
		} catch (Exception e) {
			logger.error("数据库安装失败！");
			System.exit(-1);
		}
		return WEB_WORK_QUEUES;
	}

	
	
	public String getDatabaseName() {
		return DATABASE_NAME;
	}
	
	@Override
	public void close() {
		super.close();
		environment.cleanLog();
		environment.close();
	}
	
	@Override
	public void put(String key, ArticleLink e) {
		ArticleLink tmp = getFirst(key);
		if(tmp != null) {
			return ;
		}
		super.put(key, e);
	}
	
	/**
	 * 消耗工作队列中的资源
	 */
	public ArrayList<ArticleLink> consume(int max) {
		try {
			lock.lock();
			ArrayList<ArticleLink> list = get(max);
			delete(list.size());
			return list;
		} finally {
			lock.unlock();
		}
	}
	/**
	 * 消耗工作队列中的资源
	 */
	public ArticleLink consume() {
		try {
			lock.lock();
			ArticleLink list = get();
			if(list != null) {
				delete(list.getPath());
			}
			return list;
		} finally {
			lock.unlock();
		}
	}

	@Override
	protected Class<? extends Comparator<byte[]>> getComparator() {
		return ArticleLinkCompartor.class;
	}

	@Override
	protected TupleBinding<ArticleLink> getTupleBinding() {
		return new ArticleLinkTupleBinding();
	}
	
	@Override
	public void sync() {
		logger.info("数据库【{}】现完成数据同步！",getDatabaseName());
		super.sync();
	}
	
	/**
	 * 配置环境
	 * 
	 * @return
	 */
	private EnvironmentConfig deploy() {
		EnvironmentConfig envConfig = new EnvironmentConfig();
		envConfig.setAllowCreate(true);
		envConfig.setTransactional(true);
		envConfig.setLocking(true);
		return envConfig;
	}

	public Environment setup(String path) throws Exception {
		if (path == null || path.length() == 0) {
			throw new IOException("请指定数据库目录！");
		}
		File folder = new File(path); // 数据库安装目录
		File envHome = new File(path + "/frontier");// 数据库环境的主目录
		createHome(folder, envHome);
		EnvironmentConfig envConfig = deploy(); // 环境属性设置
		return new Environment(envHome, envConfig);
	}
	
	private void createHome(File folder, File envHome) throws IOException {
		if (!folder.exists()) {
			if (!folder.mkdirs()) {
				logger.info("创建安装目录失败");
				throw new IOException();
			}
			if (!envHome.exists()) {
				if (!envHome.mkdir()) {
					logger.info("数据库安装目录创建失败");
					throw new IOException();
				}
			}
		}
	}
	
	public void remove() {
		environment.removeDatabase(null, DATABASE_NAME);
	}
	
	
}
